/*
* Copyright (C) 2004 Anthony Smith
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* ----------------------------------------------------------------------------
* TITLE $Id$
* ---------------------------------------------------------------------------
*
* --------------------------------------------------------------------------*/
package opendbcopy.plugin.schemageneration.gui;
import java.awt.BorderLayout;
import java.util.Iterator;
import java.util.List;
import java.util.Observable;
import java.util.Vector;
import javax.swing.BorderFactory;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTree;
import javax.swing.border.Border;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import opendbcopy.config.XMLTags;
import opendbcopy.controller.MainController;
import opendbcopy.gui.DynamicPanel;
import opendbcopy.gui.PluginGui;
import opendbcopy.plugin.model.database.DatabaseModel;
import opendbcopy.plugin.model.exception.MissingElementException;
import opendbcopy.swing.JTableX;
import opendbcopy.swing.RowEditorModel;
import org.jdom.Element;
/**
* class description
*
* @author Anthony Smith
* @version $Revision$
*/
public class PanelMappingColumn extends DynamicPanel {
private DatabaseModel model;
private Object[][] dataMapping;
private Object[][] dataProcess;
private String currentTable;
private DefaultMutableTreeNode top;
private MappingColumnModel mappingColumnModel;
private ProcessColumnModel processColumnModel;
private RowEditorModel rowModel;
private DefaultCellEditor dce;
private boolean select_all = false;
private Border borderRightPanel;
private BorderLayout borderLayout = new BorderLayout();
private BorderLayout borderLayoutRight = new BorderLayout();
private JPanel panelOptions = new JPanel();
private JPanel panelRight = new JPanel();
private JPanel panelMappingColumns = null;
private JPanel panelProcessColumns = null;
private JSplitPane splitPane = new JSplitPane();
private JScrollPane scrollPaneTree = null;
private JScrollPane scrollPaneTables = null;
private JTree treeSourceTables = new JTree();
private JTableX tableMappingColumn = new JTableX();
private JTableX tableProcessColumn = new JTableX();
private JLabel labelSelect = new JLabel();
private JLabel labelInfo = new JLabel();
/**
* Creates a new PanelProcessColumn object.
*
* @param controller DOCUMENT ME!
* @param pluginGui DOCUMENT ME!
* @param registerAsObserver DOCUMENT ME!
*
* @throws Exception DOCUMENT ME!
*/
public PanelMappingColumn(MainController controller,
PluginGui workingMode,
Boolean registerAsObserver) throws Exception {
super(controller, workingMode, registerAsObserver);
model = (DatabaseModel) super.model;
guiInit();
loadMappingTables();
}
/**
* DOCUMENT ME!
*
* @param o DOCUMENT ME!
* @param obj DOCUMENT ME!
*/
public final void update(Observable o,
Object obj) {
}
/**
* DOCUMENT ME!
*/
public final void onSelect() {
try {
loadMappingTables();
} catch (Exception e) {
postException(e);
}
}
/**
* DOCUMENT ME!
*
* @throws MissingElementException DOCUMENT ME!
*/
public final void loadMappingTables() throws MissingElementException {
if (model.isMappingSetup()) {
// remove component
splitPane.remove(scrollPaneTree);
top = new DefaultMutableTreeNode(rm.getString("text.column.mappedSourceTableView"));
createMappingNodes(top);
treeSourceTables = new JTree(top);
// Listen for when the selection changes.
treeSourceTables.addTreeSelectionListener(new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent e) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) treeSourceTables.getLastSelectedPathComponent();
if (node == null) {
return;
}
if (node.getLevel() == 1) {
try {
loadMappingColumns(node.toString());
} catch (Exception ex) {
postException(ex);
}
}
}
});
// add component
scrollPaneTree = new JScrollPane(treeSourceTables);
splitPane.add(scrollPaneTree);
splitPane.updateUI();
// if visible remove panels on right hand side
if ((panelRight != null) && (panelMappingColumns != null) && (panelProcessColumns != null)) {
panelRight.remove(panelMappingColumns);
panelRight.remove(panelProcessColumns);
}
}
}
/**
* DOCUMENT ME!
*
* @param tableName DOCUMENT ME!
*
* @throws MissingElementException DOCUMENT ME!
*/
private void loadMappingColumns(String tableName) throws MissingElementException {
currentTable = tableName;
// remove components if existing
if ((panelRight != null) && (panelMappingColumns != null) && (panelProcessColumns != null)) {
panelMappingColumns.removeAll();
panelProcessColumns.removeAll();
try {
panelRight.remove(panelMappingColumns);
panelRight.remove(panelProcessColumns);
} catch (Exception e) {
// who cares
}
}
mappingColumnModel = new MappingColumnModel();
processColumnModel = new ProcessColumnModel();
rowModel = new RowEditorModel();
// init table data
initTableData(tableName);
tableMappingColumn = new JTableX(mappingColumnModel);
tableProcessColumn = new JTableX(processColumnModel);
// tell the JTableX which RowEditorModel we are using
tableMappingColumn.setRowEditorModel(rowModel);
panelMappingColumns.add(tableMappingColumn.getTableHeader(), BorderLayout.PAGE_START);
panelMappingColumns.add(tableMappingColumn, BorderLayout.CENTER);
panelProcessColumns.add(tableProcessColumn.getTableHeader(), BorderLayout.PAGE_START);
panelProcessColumns.add(tableProcessColumn, BorderLayout.CENTER);
panelRight.add(panelMappingColumns, BorderLayout.CENTER);
panelRight.add(panelProcessColumns, BorderLayout.EAST);
panelRight.updateUI();
}
/**
* DOCUMENT ME!
*
* @param tableName DOCUMENT ME!
*
* @throws MissingElementException DOCUMENT ME!
*/
private void initTableData(String tableName) throws MissingElementException {
Element sourceTable = model.getMappingSourceTable(currentTable);
int nbrSourceColumns = sourceTable.getChildren(XMLTags.COLUMN).size();
dataMapping = new Object[nbrSourceColumns][2];
dataProcess = new Object[nbrSourceColumns][1];
for (int row = 0; row < mappingColumnModel.getRowCount(); row++) {
dataMapping[row][0] = new String("");
dataMapping[row][1] = new String("");
dataProcess[row][0] = new Boolean(false);
}
Iterator itMappingColumns = sourceTable.getChildren(XMLTags.COLUMN).iterator();
int row = 0;
while (itMappingColumns.hasNext()) {
Element columnMapping = (Element) itMappingColumns.next();
dataMapping[row][0] = columnMapping.getAttributeValue(XMLTags.SOURCE_DB);
// create a new JComboBox and editor for this row
JComboBox combo = getDestinationColumnsComboBox(sourceTable.getAttributeValue(XMLTags.DESTINATION_DB), columnMapping.getAttributeValue(XMLTags.DESTINATION_DB));
dce = new DefaultCellEditor(combo);
rowModel.addEditorForRow(row, dce);
// set default selected item
dataMapping[row][1] = combo.getSelectedItem();
dataProcess[row][0] = new Boolean(columnMapping.getAttributeValue(XMLTags.PROCESS));
row++;
}
}
/**
* DOCUMENT ME!
*
* @param destinationTableName DOCUMENT ME!
* @param destinationColumnName DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws MissingElementException DOCUMENT ME!
*/
private JComboBox getDestinationColumnsComboBox(String destinationTableName,
String destinationColumnName) throws MissingElementException {
JComboBox combo = null;
combo = new JComboBox(createComboBoxVector(model.getDestinationColumns(destinationTableName)));
// if destinationTableName is empty selects empty element as selected element
combo.setSelectedItem(destinationColumnName);
return combo;
}
/**
* DOCUMENT ME!
*
* @param columns DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
private Vector createComboBoxVector(List columns) {
Vector destinationColumnsComboBoxValues = new Vector();
// add empty element
destinationColumnsComboBoxValues.add("");
if (columns.size() > 0) {
Iterator itColumns = columns.iterator();
while (itColumns.hasNext()) {
Element column = (Element) itColumns.next();
destinationColumnsComboBoxValues.add(column.getAttributeValue(XMLTags.NAME));
}
}
return destinationColumnsComboBoxValues;
}
/**
* DOCUMENT ME!
*
* @param top DOCUMENT ME!
*
* @throws MissingElementException DOCUMENT ME!
*/
private void createMappingNodes(DefaultMutableTreeNode top) throws MissingElementException {
DefaultMutableTreeNode table = null;
Iterator itMappingTables = model.getMappingTables().iterator();
while (itMappingTables.hasNext()) {
Element tableElement = (Element) itMappingTables.next();
if ((tableElement.getAttributeValue(XMLTags.MAPPED).compareTo("true") == 0) && (tableElement.getAttributeValue(XMLTags.PROCESS).compareTo("true") == 0)) {
table = new DefaultMutableTreeNode(tableElement.getAttributeValue(XMLTags.SOURCE_DB));
top.add(table);
}
}
}
/**
* DOCUMENT ME!
*/
private void guiInit() {
borderLayout.setHgap(10);
borderLayout.setVgap(10);
borderRightPanel = BorderFactory.createEmptyBorder(0, 0, 0, 0);
panelOptions.setLayout(null);
splitPane.setBorder(BorderFactory.createEmptyBorder());
splitPane.setOpaque(false);
splitPane.setOneTouchExpandable(true);
splitPane.setContinuousLayout(true);
splitPane.setResizeWeight(0.3);
splitPane.setLastDividerLocation(splitPane.getDividerLocation());
borderLayoutRight.setHgap(0);
borderLayoutRight.setVgap(0);
panelRight.setLayout(borderLayoutRight);
panelMappingColumns = new JPanel(new BorderLayout());
panelProcessColumns = new JPanel(new BorderLayout());
panelRight.add(panelMappingColumns, BorderLayout.CENTER);
panelRight.add(panelProcessColumns, BorderLayout.EAST);
panelRight.setBorder(borderRightPanel);
splitPane.setDividerLocation(splitPane.getLastDividerLocation());
scrollPaneTree = new JScrollPane();
scrollPaneTables = new JScrollPane(panelRight);
splitPane.add(scrollPaneTree, JSplitPane.LEFT);
splitPane.add(scrollPaneTables, JSplitPane.RIGHT);
this.setLayout(borderLayout);
this.add(panelOptions, BorderLayout.NORTH);
this.add(splitPane, BorderLayout.CENTER);
}
/**
* class description
*
* @author Anthony Smith
* @version $Revision$
*/
class MappingColumnModel extends AbstractTableModel {
private String[] columnNames = { rm.getString("text.column.sourceColumn"), rm.getString("text.column.destinationColumn") };
public final Object[] longValues = { "abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz" };
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public final int getColumnCount() {
return columnNames.length;
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public final int getRowCount() {
return dataMapping.length;
}
/**
* DOCUMENT ME!
*
* @param col DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public final String getColumnName(int col) {
return columnNames[col];
}
/**
* DOCUMENT ME!
*
* @param row DOCUMENT ME!
* @param col DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public final Object getValueAt(int row,
int col) {
return dataMapping[row][col];
}
/*
* JTable uses this method to determine the default renderer/
* editor for each cell. If we didn't implement this method,
* then the last column would contain text ("true"/"false"),
* rather than a check box.
*/
public final Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
/*
* Don't need to implement this method unless your table's
* editable.
*/
public final boolean isCellEditable(int row,
int col) {
//Note that the data/cell address is constant,
//no matter where the cell appears onscreen.
if (col < 1) {
return false;
} else {
return true;
}
}
/*
* Don't need to implement this method unless your table's
* data can change.
*/
public final void setValueAt(Object value,
int row,
int col) {
dataMapping[row][col] = value;
Element mapping_column = null;
// check if value is not empty
if (((String) value).length() > 0) {
try {
mapping_column = model.getMappingSourceColumn(currentTable, (String) dataMapping[row][col - 1]);
if (mapping_column != null) {
mapping_column.setAttribute(XMLTags.DESTINATION_DB, (String) dataMapping[row][col]);
mapping_column.setAttribute(XMLTags.MAPPED, "true");
processColumnModel.setValueAt(new Boolean(true), row, 0);
}
} catch (Exception e) {
postException(e);
}
} else {
try {
mapping_column = model.getMappingSourceColumn(currentTable, (String) dataMapping[row][col - 1]);
mapping_column.setAttribute(XMLTags.MAPPED, "false");
processColumnModel.setValueAt(new Boolean(false), row, 0);
} catch (Exception e) {
postException(e);
}
}
fireTableCellUpdated(row, col);
}
}
/**
* class description
*
* @author Anthony Smith
* @version $Revision$
*/
class ProcessColumnModel extends AbstractTableModel {
private String[] columnNames = { rm.getString("text.column.process") };
public final Object[] longValues = { new Boolean(false) };
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public final int getColumnCount() {
return columnNames.length;
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public final int getRowCount() {
return dataProcess.length;
}
/**
* DOCUMENT ME!
*
* @param col DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public final String getColumnName(int col) {
return columnNames[col];
}
/**
* DOCUMENT ME!
*
* @param row DOCUMENT ME!
* @param col DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public final Object getValueAt(int row,
int col) {
return dataProcess[row][col];
}
/*
* JTable uses this method to determine the default renderer/
* editor for each cell. If we didn't implement this method,
* then the last column would contain text ("true"/"false"),
* rather than a check box.
*/
public final Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
/*
* Don't need to implement this method unless your table's
* data can change.
*/
public final void setValueAt(Object value,
int row,
int col) {
dataProcess[row][col] = value;
try {
Element mapping_column = model.getMappingSourceColumn(currentTable, (String) dataMapping[row][col]);
if (mapping_column != null) {
if (value.equals(new Boolean(true))) {
mapping_column.setAttribute(XMLTags.PROCESS, "true");
} else {
mapping_column.setAttribute(XMLTags.PROCESS, "false");
}
}
} catch (Exception e) {
postException(e);
}
fireTableCellUpdated(row, col);
}
/**
* DOCUMENT ME!
*
* @param row DOCUMENT ME!
* @param col DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public final boolean isCellEditable(int row,
int col) {
return true;
}
}
}